package com.example.demo.friendship.serviceimpl;

import com.example.demo.friendship.dao.mongdb.PagePostDao;
import com.example.demo.friendship.model.mongodb.PagePostCollected;
import com.mongodb.*;
import com.mongodb.client.MongoDatabase;
import lombok.extern.slf4j.Slf4j;
import org.bson.BsonJavaScript;
import org.bson.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.mongodb.core.DbCallback;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.mapreduce.MapReduceOptions;
import org.springframework.data.mongodb.core.mapreduce.MapReduceResults;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

import static com.mongodb.DBCollection.ID_FIELD_NAME;

@Slf4j
@Service
public class PagePostServiceImpl {

    @Autowired
    private PagePostDao pagePostDao;
    @Autowired
    private MongoTemplate mongoTemplate;

    public Object savePost(){

        List<String> domains = new ArrayList<>();
        domains.add("A.com");
        domains.add("B.com");
        domains.add("C.com");

        PagePostCollected pagePostCollected = new PagePostCollected();
        pagePostCollected.setCommentCount((int) (Math.random() * 100000));
        pagePostCollected.setDomain(domains.get((int) (Math.random()*3)));
        pagePostCollected.setFbPageId(System.currentTimeMillis());
        pagePostCollected.setLikeCount((int) (Math.random() * 100000));
        pagePostCollected.setPostId(System.currentTimeMillis());
        pagePostCollected.setShareCount((int) (Math.random() * 100000));

        return pagePostDao.save(pagePostCollected);
    }

    public Object addFansCount(){
        Update update = new Update();
        update.set("fansCount",100000);
        return this.mongoTemplate.updateMulti(new Query(),update,PagePostCollected.class);
    }

    public Object doMapReduce() {
        String map = "function(){ emit(this.domain, {count:1,like:this.likeCount,share:this.shareCount,comment:this.commentCount,fans:this.fansCount}); } ";
        String reduce = " function (key, values) {  var reducedValue = { totalLike : 0,totalShare : 0,totalComment : 0,rateLike : 0,count:0,rateLikeAvg:0 };  values.forEach(function(val) {  reducedValue.count++;  reducedValue.totalLike += val.like;  reducedValue.totalShare += val.share;  reducedValue.totalComment += val.comment; if(val.fans) { reducedValue.rateLike += val.like/val.fans; }  });  reducedValue.rateLikeAvg = reducedValue.rateLike / reducedValue.count;  return reducedValue;  } ";
        MapReduceOptions mrO = new MapReduceOptions();
        mrO.outputCollection("result_post_page").outputTypeReplace();
        MapReduceResults<PagePostCollected> mapReduce = mongoTemplate.mapReduce("pagePostCollected",map,reduce,mrO,PagePostCollected.class);
        return mapReduce;
//        return o;

//        return mongoTemplate.execute(new DbCallback<Object>() {
//            @Override
//            public Object doInDB(MongoDatabase db) throws MongoException, DataAccessException {
//                BasicDBObject command = new BasicDBObject()
//                        .append("mapReduce","pagePostCollected")
//                        .append("map", new BsonJavaScript(map))
//                        .append("reduce", new BsonJavaScript(reduce))
//                        .append("out",new BasicDBObject().append("replace", "result"));
//
//                Document commandResult = db.runCommand(command);
//                log.info("result :" + commandResult);
//                return null;
//            }
//        });

    }

}
